home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / src / tools / process-uucp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-03-28  |  9.9 KB  |  397 lines

  1. /*
  2.  * process-uucp.c -- Make mmdf tables from uucp project derived information.
  3.  *
  4.  * USAGE: process-uucp [ -d domain ... ] [ -r relay-host ] 
  5.  *            [ -c host ... ] file ...
  6.  *
  7.  * -d domain        generate a domain table for the domain.
  8.  *            The file name is "wrkdmn.uucp-dom.ain", and
  9.  *            the entries are like:
  10.  *
  11.  *    dom: dom.ain
  12.  *
  13.  * -r relay-host     have the entries in the domain file be
  14.  *            routed through "relay-host". i.e.
  15.  *
  16.  *    dom: dom.ain, relay-host
  17.  *
  18.  * -c host        This causes the wrkchn.uucp-uucp file to be split into
  19.  *            multiple files.  If a path has its' first component
  20.  *            as the named host, then the entry will be put
  21.  *            into a seperate file named "wrkchn.uucp-host".
  22.  *
  23.  * The input file is the output of pathalias.  The format is:
  24.  *
  25.  * {host,domain}    a!b!c!...%s...
  26.  *
  27.  * From this we make both domain tables and channel tables.
  28.  *
  29.  * There are a couple of files which are automatically created:
  30.  *
  31.  * wrkchn.uucp-uucp    This contains domain:path entries for any paths
  32.  *            which did not match hosts given in the -c list.
  33.  * wrkdmn.uucp-top    This domains dom:dom.ain entries for domains
  34.  *            which did not match domains given in -d's.
  35.  *
  36.  * A word about the file naming scheme.  The general format of file
  37.  * names which I use on tables is "<type>.<source>-<subtype>".
  38.  * "<type>" is something like domain, chan, or alias.  "<source>"
  39.  * is some identifier saying where the information came from, like
  40.  * uucp or bitnet.  "<subtype>" is something like domain for domain
  41.  * tables, channel name for channel tables, or some other sort of
  42.  * identifier depending on what the table is for.  (For instance,
  43.  * I also have alias-global, alias-forward, and alias-local tables).
  44.  *
  45.  * Suggested use is something like:
  46.  *
  47.  * process-uucp -d uucp -d edu -d arpa pathalias-output-file
  48.  *
  49.  * AUTHOR:
  50.  * 
  51.  * David Herron, University of Kentucky Mathematical Sciences
  52.  * Mon Nov 16 17:39:18 EST 1987
  53.  */
  54.  
  55. #include <stdio.h>
  56. #include <ctype.h>
  57.  
  58. struct namelist {
  59.     char *name;
  60.     char *fname;
  61.     /* FILE *ofile; */
  62. };
  63.  
  64. /* File name prefixes */
  65. #define WRK_CHAN    "wrkchn.uucp"
  66. #define WRK_DMN        "wrkdmn.uucp"
  67.  
  68. void process();
  69. char buf[BUFSIZ];
  70.  
  71.  
  72. void addfile();
  73. char *files[BUFSIZ];
  74. int numfiles = 0;
  75.  
  76.  
  77. void addomain();
  78. struct namelist domains[BUFSIZ];
  79. int numdomains = 0;
  80.  
  81.  
  82. void addhost();
  83. struct namelist hosts[BUFSIZ];
  84. int numhosts = 0;
  85.  
  86.  
  87. char *lowerify();
  88. char *RelayHost = (char *)0;
  89.  
  90. extern char *malloc();
  91.  
  92. main(argc, argv)
  93. int argc;
  94. char **argv;
  95. {
  96.     int i;
  97.  
  98.     if (argc <= 1) {
  99.         fprintf(stderr, "Usage: %s file ...\n", argv[0]);
  100.         exit(1);
  101.     }
  102.     sprintf(buf, "%s-uucp", WRK_CHAN);
  103.     close(creat(buf, 0644));
  104.     for (i=1; i < argc; i++) {
  105.         if (argv[i][0] == '-') {
  106.             switch(argv[i][1]) {
  107.             case 'd':
  108.                 i++;
  109.                 printf("addomain(%s);\n", argv[i]);
  110.                 addomain(argv[i]);
  111.                 break;
  112.             case 'c':
  113.                 i++;
  114.                 printf("addhost(%s);\n", argv[i]);
  115.                 addhost(argv[i]);
  116.                 break;
  117.             case 'r':
  118.                 i++;
  119.                 RelayHost = lowerify(argv[i]);
  120.                 printf("relay-host: %s\n", RelayHost);
  121.                 break;
  122.             default:
  123.                 break;
  124.             }
  125.         }
  126.         else {
  127.             addfile(argv[i]);
  128.         }
  129.     }
  130.     for (i=0; i<numfiles; i++) {
  131.         /* printf("process(%s);\n", files[i]); */
  132.         process(files[i]);
  133.     }
  134.     exit(0);
  135. }
  136.  
  137. void
  138. addomain(s)
  139. char *s;
  140. {
  141.     int slen;
  142.  
  143.     domains[numdomains].name = s;
  144.     slen = strlen(WRK_DMN) + 1 + strlen(s) + 1;
  145.     domains[numdomains].fname = malloc(slen);
  146.     sprintf(domains[numdomains].fname, "%s-%s", WRK_DMN, s);
  147.     numdomains++;
  148. }
  149.  
  150. void
  151. addhost(s)
  152. char *s;
  153. {
  154.     int slen;
  155.  
  156.     hosts[numhosts].name = s;
  157.     slen = strlen(WRK_DMN) + 1 + strlen(s) + 1;
  158.     hosts[numhosts].fname = malloc(slen);
  159.     sprintf(hosts[numhosts].fname, "%s-%s", WRK_CHAN, s);
  160.     numhosts++;
  161. }
  162.  
  163. void
  164. addfile(s)
  165. char *s;
  166. {
  167.     files[numfiles++] = s;
  168. }
  169.  
  170. char *
  171. lowerify(s)
  172. char *s;
  173. {
  174.     register char *sp = s;
  175.  
  176.     while (*sp != '\0') {
  177.         if (isupper(*sp))
  178.             *sp = tolower(*sp);
  179.         sp++;
  180.     }
  181.     return(s);
  182. }
  183.  
  184. /*
  185.  * indomain(name, domain) -- Test to see if the given name is 
  186.  * within a domain ... we do this as a sort of reverse-strcmp().
  187.  *
  188.  * The return value is NULL if it is not, and a pointer within the
  189.  * tested name if it is.
  190.  */
  191. char *
  192. indomain(name, domain)
  193. char *name, *domain;
  194. {
  195.     register char *namp, *domp;
  196.  
  197.     namp = name; domp = domain;
  198.     if (!namp || !domp)
  199.         return(NULL);
  200.     /* printf("indomain(%s, %s); -- ", name, domain); */
  201.     /* Find the end of the strings */
  202.     namp = &(name[strlen(name)-1]);
  203.     domp = &(domain[strlen(domain)-1]);
  204.     /* printf("start at namp=<%s> domp=<%s> -- ", namp, domp); */
  205.     for (; namp>=name && domp>=domain; namp--, domp--)
  206.         if (namp[0] != domp[0])
  207.             break;
  208.     namp++; domp++;
  209.     /* printf("match at namp=<%s> domp=<%s>\n", namp, domp); */
  210.     if (
  211.            (namp>name && domp==domain && namp[-1]=='.') 
  212.         || namp == name
  213.        )
  214.         return(namp);
  215.     else
  216.         return(NULL);
  217. }
  218.  
  219. /* These have to be here because the compiler chokes if they're
  220.  * inside process().
  221.  */
  222. char pathbuf[BUFSIZ], dmnbuf[BUFSIZ], bf2[BUFSIZ];
  223.  
  224. /*
  225.  * process(file) -- Process the file making all the tables which 
  226.  * which we were told to make on the command line.
  227.  *
  228.  * A note about the algorithm.  If you read the code below you will
  229.  * notice that I am constantly open()ing and close()ing files to
  230.  * append records to the end of the files.  This is because, in
  231.  * theory at least, someone could have 50 domain files that they
  232.  * generate from this program.  
  233.  *
  234.  * Maybe in practice one will never have more than 10 (to pick a number 
  235.  * out of the air).  If you really want to "fix" this, be my guest.  It 
  236.  * should be a fairly trivial re-write.  The "fix" I have in mind is to
  237.  * change "domains[]" into an array of structures remembering the domain
  238.  * name, the file name for the domain, and the FILE * pointing to that
  239.  * file.  Then there are a few places below where one looks up the
  240.  * file name, fopen()s the file in "a" mode, write the record, and close
  241.  * the file.  One would need to change those places to merely write the 
  242.  * record after looking up the FILE * in the struct namelist.
  243.  *
  244.  * NOTE NOTE NOTE ... The procedure as it is opens files in append mode
  245.  * and there's no automatic truncation of any files.  You will have to
  246.  * do this by hand.  (Well, engrave it in your shell script which processes
  247.  * the pathalias output).
  248.  */
  249. void
  250. process(file)
  251. char *file;
  252. {
  253.     register char *sp, *sp2;
  254.     register int i;
  255.     FILE *ifile, *cfile, *tcfile, *dfile, *topfile;
  256.     int hlen;
  257.     char *index(), *strcpy(), *strcat();
  258.  
  259.     ifile = fopen(file, "r");
  260.     if (ifile == NULL) {
  261.         /* printf("Open of %s failed with errno=%d\n", file, errno); */
  262.         perror(file);
  263.         return;
  264.     }
  265.     sprintf(buf, "%s-uucp", WRK_CHAN);
  266.     cfile = fopen(buf, "a");
  267.     if (cfile == NULL) {
  268.         /* printf("Open of %s failed with errno=%d\n", buf, errno); */
  269.         perror(buf);
  270.         fclose(ifile);
  271.         return;
  272.     }
  273.     sprintf(buf, "%s-top", WRK_DMN);
  274.     topfile = fopen(buf, "a");
  275.     if (topfile == NULL) {
  276.         /* printf("Open of %s failed with errno=%d\n", buf, errno); */
  277.         perror(buf);
  278.         fclose(ifile);
  279.         fclose(cfile);
  280.         return;
  281.     }
  282.     while (fgets(buf, BUFSIZ, ifile) != NULL) {
  283.         if ((sp = index(buf, '\n')) != NULL)
  284.             *sp = '\0';
  285.         /* copy the domain part */
  286.         for (sp=buf, sp2=dmnbuf;
  287.              *sp!='\0' && *sp!=' ' && *sp!='\t';
  288.              sp++, sp2++)
  289.             *sp2 = *sp;
  290.         *sp2 = '\0';
  291.         /* Then the path part */
  292.         if (*sp != '\0') {
  293.             while (*sp==' ' || *sp=='\t')
  294.                  sp++;
  295.             for (sp2=pathbuf;
  296.                  *sp!='\0' && *sp!=' ' && *sp!='\t';
  297.                  sp++, sp2++)
  298.                 *sp2 = *sp;
  299.             *sp2 = '\0';
  300.         }
  301.         if (pathbuf[0] == '\0')
  302.             strcpy(pathbuf, "NO-PATH-GIVEN!%s");
  303.         /* printf("before = %s\n", dmnbuf); */
  304.         (void) lowerify(dmnbuf);
  305.         /* printf("after = %s\n", dmnbuf); */
  306.         if ((sp = index(dmnbuf, '.')) == NULL)
  307.             strcat(dmnbuf, ".uucp");
  308.         if (dmnbuf[0] == '.')
  309.             for (sp = dmnbuf; *sp != '\0'; sp++)
  310.                 *sp = *(sp+1);
  311.         /*
  312.          * If the given domain name is within one of those for which
  313.          * we have a domain table, output it into the domain table
  314.          * and into the channel table.
  315.          */
  316.         for (i=0; i<numdomains; i++) {
  317.             if ((sp2=indomain(dmnbuf, domains[i].name)) != NULL) {
  318.                 if (sp2 > dmnbuf) {
  319.                     dfile = fopen(domains[i].fname, "a");
  320.                     /* write out first part of dom.ain */
  321.                     for (sp=dmnbuf; sp < (sp2-1); sp++)
  322.                         fputc(*sp, dfile);
  323.                     if (RelayHost)
  324.                         fprintf(dfile, ":\t%s, %s\n", 
  325.                             dmnbuf, RelayHost);
  326.                     else
  327.                         fprintf(dfile, ":\t%s\n", dmnbuf);
  328.                     fclose(dfile);
  329.                     break;
  330.                 }
  331.                 else {
  332.                     /*
  333.                      * This case is for when the name we're
  334.                      * testing fully matches the domain name
  335.                      * for one of the tables.  We aren't 
  336.                      * supposed to make an entry for him
  337.                      * in this table, but in the table for
  338.                      * the parent domain.  But we don't
  339.                      * know here whether we are keeping
  340.                      * a table for that domain ... HOWEVER,
  341.                      * if we keep looping through the rest of
  342.                      * the table names we will eventually 
  343.                      * find out.
  344.                      */
  345.                     continue;
  346.                 }
  347.             }
  348.         }
  349.         /*
  350.          * This case is for when we've run through the entire list 
  351.          * of domains for which we have tables and the name we
  352.          * have does not fit with any of those.  So, we insert
  353.          * it into the top-level table.
  354.          */
  355.         if (i == numdomains) {
  356.             if (RelayHost)
  357.                 fprintf(topfile, "%s:\t%s, %s\n", 
  358.                     dmnbuf, dmnbuf, RelayHost);
  359.             else
  360.                 fprintf(topfile, "%s:\t%s\n", dmnbuf, dmnbuf);
  361.         }
  362.         /*
  363.          * This section handles making entries in the channel table.
  364.          */
  365.         if (numhosts > 0) {
  366.             for (i=0; i<numhosts; i++) {
  367.                 hlen = strlen(hosts[i].name);
  368.                 /* This shortcuts if we already know that
  369.                  * the names CANNOT match. i.e. if the next
  370.                  * character is not '!', then the lengths
  371.                  * of the two names are not the same.
  372.                  */
  373.                 if (pathbuf[hlen] != '!')
  374.                     continue;
  375.                 if (strncmp(pathbuf, hosts[i].name, hlen) != 0)
  376.                     continue;
  377.                 tcfile = fopen(hosts[i].fname, "a");
  378.                 fprintf(tcfile, "%s:\t%s\n", dmnbuf, pathbuf);
  379.                 fclose(tcfile);
  380.                 break;
  381.             }
  382.             /* If we make it all the way through the list, then
  383.              * we didn't write out the record to a file.  Put
  384.              * the record out into the default file.
  385.              */
  386.             if (i == numhosts)
  387.                 fprintf(cfile, "%s:\t%s\n", dmnbuf, pathbuf);
  388.         }
  389.         else
  390.             fprintf(cfile, "%s:\t%s\n", dmnbuf, pathbuf);
  391.     }
  392.     /* printf("done with %s\n", file); */
  393.     fclose(cfile);
  394.     fclose(ifile);
  395.     fclose(topfile);
  396. }
  397.